//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package net.mingsoft.basic.exception;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.mingsoft.base.entity.ResultData;
import net.mingsoft.base.util.BundleUtil;
import net.mingsoft.basic.biz.ILogBiz;
import net.mingsoft.basic.entity.LogEntity;
import net.mingsoft.basic.entity.ManagerEntity;
import net.mingsoft.basic.util.BasicUtil;
import net.mingsoft.basic.util.CalculationUtil;
import net.mingsoft.basic.util.IpUtils;
import net.mingsoft.basic.util.SpringUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.CredentialsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.session.ExpiredSessionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpStatus;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;

@ControllerAdvice
public class GlobalExceptionResolver extends DefaultHandlerExceptionResolver {
    protected final Logger LOG = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private ILogBiz logBiz;

    public GlobalExceptionResolver() {
    }

    /** @deprecated */
    @ExceptionHandler({BusinessException.class})
    @Deprecated
    public ModelAndView handleBusinessException(HttpServletRequest request, HttpServletResponse response, BusinessException e) {
        this.LOG.debug("handleBusinessException");
        response.setStatus(e.getCode().value());
        return this.render(request, response, ResultData.build().code(e.getCode()).data(e.getData()).msg(e.getMsg()), e);
    }

    @ExceptionHandler({net.mingsoft.base.exception.BusinessException.class})
    public ModelAndView handleBusinessException(HttpServletRequest request, HttpServletResponse response, net.mingsoft.base.exception.BusinessException e) {
        this.LOG.debug("handleBusinessException");
        response.setStatus(e.getCode().value());
        return this.render(request, response, ResultData.build().code(e.getCode()).data(e.getData()).msg(e.getMsg()), e);
    }

    @ExceptionHandler({Exception.class})
    public ModelAndView handleException(HttpServletRequest request, HttpServletResponse response, Exception e) {
        this.LOG.debug("handleException");
        response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        return this.render(request, response, ResultData.build().code(HttpStatus.INTERNAL_SERVER_ERROR).msg(e.getStackTrace()[0].toString().concat(":").concat(e.toString())), e);
    }

    @ExceptionHandler({BadSqlGrammarException.class})
    public ModelAndView handleSqlException(HttpServletRequest request, HttpServletResponse response, Exception e) {
        this.LOG.debug("handleSqlException");
        response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        return this.render(request, response, ResultData.build().code(HttpStatus.INTERNAL_SERVER_ERROR).msg("SQL异常,请联系管理员!"), e);
    }

    @ExceptionHandler({MaxUploadSizeExceededException.class})
    public ModelAndView uploadException(HttpServletRequest request, HttpServletResponse response, MaxUploadSizeExceededException e) throws IOException {
        this.LOG.debug("MaxUploadSizeExceededException");
        response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        long maxFileSize = Long.parseLong((String)((Environment)SpringUtil.getBean(Environment.class)).getProperty("ms.upload.multipart.max-file-size", String.class, "1024"));
        return this.render(request, response, ResultData.build().code(HttpStatus.INTERNAL_SERVER_ERROR).msg(BundleUtil.getString("net.mingsoft.basic.resources.resources", "upload.max.size", new String[]{CalculationUtil.convertSpaceUnit(maxFileSize)})), e);
    }

    @ExceptionHandler({NoHandlerFoundException.class})
    public ModelAndView handleNoHandlerFoundException(HttpServletRequest request, HttpServletResponse response, NoHandlerFoundException e) {
        this.LOG.debug("handleNoHandlerFoundException");
        return this.render(request, response, ResultData.build().code(HttpStatus.NOT_FOUND).msg("资源不存在"), e);
    }

    @ExceptionHandler({MissingServletRequestParameterException.class})
    public ModelAndView handleMissingServletRequestParameterException(HttpServletRequest request, HttpServletResponse response, MissingServletRequestParameterException e) {
        this.LOG.debug("handleMissingServletRequestParameterException");
        return this.render(request, response, ResultData.build().code(HttpStatus.BAD_REQUEST).msg("request parameter err"), e);
    }

    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    public ModelAndView handleHttpRequestMethodNotSupportedException(HttpServletRequest request, HttpServletResponse response, HttpRequestMethodNotSupportedException e) {
        this.LOG.debug("handleHttpRequestMethodNotSupportedException");
        return this.render(request, response, ResultData.build().code(HttpStatus.METHOD_NOT_ALLOWED).msg("request method not support"), e);
    }

    @ExceptionHandler({BindException.class})
    public ModelAndView handleValidExceptionHandler(HttpServletRequest request, HttpServletResponse response, BindException e) {
        this.LOG.debug("handleValidExceptionHandler");
        StringBuilder message = new StringBuilder();
        List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
        Iterator var6 = fieldErrors.iterator();

        while(var6.hasNext()) {
            FieldError error = (FieldError)var6.next();
            message.append(error.getField()).append(error.getDefaultMessage()).append(",");
        }

        message = new StringBuilder(message.substring(0, message.length() - 1));
        return this.render(request, response, ResultData.build().code(HttpStatus.NOT_ACCEPTABLE).msg(message.toString()), e);
    }

    @ExceptionHandler({UnauthorizedException.class})
    public ModelAndView handleUnauthorizedException(HttpServletRequest request, HttpServletResponse response, UnauthorizedException e) {
        this.LOG.debug("handleUnauthorizedException");
        return this.render(request, response, ResultData.build().code(HttpStatus.UNAUTHORIZED).msg("无访问权限!"), e);
    }

    @ExceptionHandler({LockedAccountException.class})
    public ModelAndView handleLockedAccountException(HttpServletRequest request, HttpServletResponse response, LockedAccountException e) {
        this.LOG.debug("handleLockedAccountException");
        response.setStatus(HttpStatus.LOCKED.value());
        return this.render(request, response, ResultData.build().code(HttpStatus.LOCKED).msg(e.getMessage()), e);
    }

    @ExceptionHandler({IncorrectCredentialsException.class})
    public ModelAndView handleIncorrectCredentialsException(HttpServletRequest request, HttpServletResponse response, IncorrectCredentialsException e) {
        this.LOG.debug("IncorrectCredentialsException");
        response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        return this.render(request, response, ResultData.build().code(HttpStatus.INTERNAL_SERVER_ERROR).msg("管理员账号或密码错误"), e);
    }

    @ExceptionHandler({AuthenticationException.class})
    public ModelAndView handleAuthenticationException(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) {
        this.LOG.debug("AuthenticationException");
        response.setStatus(HttpStatus.UNAUTHORIZED.value());
        return this.render(request, response, ResultData.build().code(HttpStatus.UNAUTHORIZED).msg("AuthenticationException"), e);
    }

    @ExceptionHandler({AuthorizationException.class})
    public ModelAndView handleAuthorizationException(HttpServletRequest request, HttpServletResponse response, AuthorizationException e) {
        this.LOG.debug("AuthorizationException");
        return this.render(request, response, ResultData.build().code(HttpStatus.UNAUTHORIZED).msg("AuthorizationException"), e);
    }

    @ExceptionHandler({CredentialsException.class})
    public ModelAndView handleCredentialsException(HttpServletRequest request, HttpServletResponse response, CredentialsException e) {
        response.setStatus(HttpStatus.UNAUTHORIZED.value());
        return this.render(request, response, ResultData.build().code(HttpStatus.UNAUTHORIZED).msg("CredentialsException"), e);
    }

    @ExceptionHandler({ExpiredSessionException.class})
    public ModelAndView handleExpiredSessionException(HttpServletRequest request, HttpServletResponse response, ExpiredSessionException e) {
        this.LOG.debug("ExpiredSessionException", e);
        response.setStatus(HttpStatus.GATEWAY_TIMEOUT.value());
        return this.render(request, response, ResultData.build().code(HttpStatus.GATEWAY_TIMEOUT), e);
    }

    @ExceptionHandler({SQLException.class})
    public ModelAndView handleSQLException(HttpServletRequest request, HttpServletResponse response, SQLException e) {
        this.LOG.debug("SQLException", e);
        response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        return this.render(request, response, ResultData.build().code(HttpStatus.INTERNAL_SERVER_ERROR).msg("SQL异常,请查看系统日志"), e);
    }

    private ModelAndView render(HttpServletRequest request, HttpServletResponse response, ResultData resultData, Exception e) {
        this.LOG.debug("url: {}", request.getRequestURI());
        e.printStackTrace();
        String contextPath = request.getServletContext().getContextPath();
        request.setAttribute("base", contextPath);

        try {
            request.setAttribute("params", BasicUtil.assemblyRequestUrlParams());
        } catch (Exception var12) {
            this.LOG.error("BasicUtil.assemblyRequestUrlParams() 异常。通常由于非法提交参数导致");
        }

        if (!BasicUtil.isAjaxRequest(request)) {
            return new ModelAndView("/error/index", resultData);
        } else {
            try {
                response.setContentType("application/json;charset=UTF-8");
                response.setStatus(resultData.getCode());
                PrintWriter writer = response.getWriter();
                writer.write(JSONUtil.toJsonStr(resultData));
                writer.flush();
                writer.close();
                List<StackTraceElement> stackElements = new ArrayList();
                stackElements.addAll(Arrays.asList(e.getStackTrace()));
                LogEntity log = new LogEntity();
                log.setLogResult(e.getMessage());
                e.printStackTrace();
                stackElements=this.getAllStackTrace(log, stackElements, e.getCause());
                List<String> stackList = (List)stackElements.stream().filter((s) -> {
                    return s.getClassName().contains("net.mingsoft");
                }).map(StackTraceElement::getFileName).filter((fileName) -> {
                    return ((String)Objects.requireNonNull(fileName)).contains(".java");
                }).collect(Collectors.toList());
                List<String> className = (List)stackElements.stream().filter((s) -> {
                    return s.getClassName().contains("net.mingsoft");
                }).filter((fileName) -> {
                    return ((String)Objects.requireNonNull(fileName.getFileName())).contains(".java");
                }).map(StackTraceElement::getClassName).collect(Collectors.toList());
                if (CollUtil.isNotEmpty(className) && className.size() > 1) {
                    log.setLogMethod((String)className.get(0));
                } else {
                    log.setLogMethod(e.getStackTrace()[0].getClassName());
                }

                if (CollUtil.isNotEmpty(stackList) && className.size() > 1) {
                    log.setLogTitle((String)stackList.get(0));
                } else {
                    log.setLogMethod(e.getStackTrace()[0].getFileName());
                }

                log.setLogUrl(request.getServletPath());
                log.setLogErrorMsg(stackElements.toString());
                log.setLogLocation(IpUtils.getRealAddressByIp(BasicUtil.getIp()));
                log.setCreateDate(new Date());
                log.setLogBusinessType("error");
                log.setLogStatus("error");
                ManagerEntity manager = BasicUtil.getManager();
                if (manager != null) {
                    log.setLogUser(manager.getManagerName());
                }

                log.setLogIp(BasicUtil.getIp());
                this.logBiz.save(log);
            } catch (IOException var13) {
                var13.printStackTrace();
            }

            return null;
        }
    }

    private List<StackTraceElement> getAllStackTrace(LogEntity log, List<StackTraceElement> traceElementList, Throwable t) {
        if (t != null) {
            if (StringUtils.isBlank(log.getLogResult())) {
                log.setLogResult(t.getMessage());
            }

            traceElementList.addAll(0, Arrays.asList(t.getStackTrace()));
            this.getAllStackTrace(log, traceElementList, t.getCause());
        }

        return traceElementList;
    }
}
